package cn.ruleengine.core;

import cn.ruleengine.core.cache.DefaultFunctionCache;
import cn.ruleengine.core.decisiontable.DecisionTable;
import cn.ruleengine.core.listener.DefaultExecuteListener;
import cn.ruleengine.core.listener.ExecuteListener;
import cn.ruleengine.core.cache.FunctionCache;
import cn.ruleengine.core.rule.RuleSet;
import cn.ruleengine.core.rule.GeneralRule;
import lombok.Getter;
import org.springframework.lang.NonNull;

import java.io.Closeable;
import java.util.Objects;


/**
 * 规则引擎配置
 */
@Getter
public class RuleEngineConfiguration implements Closeable {

    /**
     * 规则执行监听器,可以动态的在规则调用之前或之后对一些规则进行特殊处理
     */
    private ExecuteListener<GeneralRule> generalRuleListener = new DefaultExecuteListener<>();

    /**
     * 规则集执行监听器,可以动态的在规则调用之前或之后对一些规则进行特殊处理
     */
    private ExecuteListener<RuleSet> ruleSetListener = new DefaultExecuteListener<>();

    /**
     * 决策表执行监听器,可以动态的在规则调用之前或之后对一些规则进行特殊处理
     */
    private ExecuteListener<DecisionTable> decisionTableExecuteListener = new DefaultExecuteListener<>();

    /**
     * 规则函数缓存实现类
     */
    private FunctionCache functionCache = new DefaultFunctionCache();

    /**
     * 规则引擎变量
     */
    private EngineVariable engineVariable = new EngineVariable();

    /**
     * 规则集缓存
     */
    private RuleEngineRuleSetCache ruleEngineRuleSetCache = new RuleEngineRuleSetCache();

    /**
     * 已发布规则集缓存
     */
    private RuleEngineRuleSetPublishCache ruleEngineRuleSetPublishCache = new RuleEngineRuleSetPublishCache();

    /**
     * 外部code和规则code映射
     */
    private MerchantMapping merchantMapping = new MerchantMapping();

    /**
     * 设置决策表执行监听器
     *
     * @param decisionTableExecuteListener 决策表执行监听器
     */
    public void setDecisionTableExecuteListener(@NonNull ExecuteListener<DecisionTable> decisionTableExecuteListener) {
        Objects.requireNonNull(decisionTableExecuteListener);
        this.decisionTableExecuteListener = decisionTableExecuteListener;
    }

    /**
     * 设置规则集执行监听器
     *
     * @param ruleSetListener 规则集执行监听器
     */
    public void setRuleSetListener(@NonNull ExecuteListener<RuleSet> ruleSetListener) {
        Objects.requireNonNull(ruleSetListener);
        this.ruleSetListener = ruleSetListener;
    }

    /**
     * 设置普通规则执行监听器
     *
     * @param generalRuleListener 普通规则执行监听器
     */
    public void setGeneralRuleListener(@NonNull ExecuteListener<GeneralRule> generalRuleListener) {
        Objects.requireNonNull(generalRuleListener);
        this.generalRuleListener = generalRuleListener;
    }

    /**
     * 设置函数缓存实现类
     *
     * @param functionCache 函数缓存实现类
     */
    public void setFunctionCache(@NonNull FunctionCache functionCache) {
        Objects.requireNonNull(functionCache);
        this.functionCache = functionCache;
    }

    /**
     * 设置规则引擎变量
     *
     * @param engineVariable 规则引擎变量
     */
    public void setEngineVariable(@NonNull EngineVariable engineVariable) {
        Objects.requireNonNull(engineVariable);
        this.engineVariable = engineVariable;
    }

    /**
     * 设置规则集和外部code映射
     *
     * @param ruleEngineRuleSetCache 规则集和外部code映射
     */
    public void setRuleEngineRuleSetCache(@NonNull RuleEngineRuleSetCache ruleEngineRuleSetCache) {
        Objects.requireNonNull(ruleEngineRuleSetCache);
        this.ruleEngineRuleSetCache = ruleEngineRuleSetCache;
    }

    /**
     * 设置发布规则集
     *
     * @param ruleEngineRuleSetPublishCache 发布规则集
     */
    public void setRuleEngineRuleSetPublishCache(@NonNull RuleEngineRuleSetPublishCache ruleEngineRuleSetPublishCache) {
        Objects.requireNonNull(ruleEngineRuleSetPublishCache);
        this.ruleEngineRuleSetPublishCache = ruleEngineRuleSetPublishCache;
    }

    @Override
    public void close() {
        this.engineVariable.close();
        this.functionCache.clear();
        this.ruleEngineRuleSetCache.close();
        this.ruleEngineRuleSetPublishCache.close();
    }

}
